﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using YAPL.Util;

namespace YAPL.Configuration {
	/// <summary>
	/// This class reads program configuration from xml file and provides
	/// access to configuration data. Implemented as singleton.
	/// </summary>
	public class Config {
		private const string CONFIG_FILE_NAME = @"config.xml";
		private const string CONFIG_PROPERTY_ELEMENT = "property";
		private const string CONFIG_PROPERTY_NAME_ATTRIBUTE = "name";
		private const string CONFIG_PROPERTY_VALUE_ATTRIBUTE = "value";
		#region configuration data keys
		public const string PARSER_ASSEMBLY_PATH = "parser_assembly_path";
		public const string PARSER_TYPE_NAME = "parser_type_name";
		public const string GENERATOR_ASSEMBLY_PATH = "generator_assembly_path";
		public const string GENERATOR_TYPE_NAME = "generator_type_name";
		public const string AST_OPTIMIZATIONS_ENABLED = "optimize_ast";
		public const string CIL_OPTIMIZATIONS_ENABLED = "optimize_cil";
		#endregion
		#region singleton methods
		private static Config _config;
		public static Config Instance {
			get {
				if (_config == null) {
					_config = new Config(CONFIG_FILE_NAME);
				}
				return _config;
			}
		}
		private Config(string fileName) {
			ReadConfiguration(fileName);
		}
		#endregion
		private readonly Dictionary<string, object> _properties = new Dictionary<string, object>();
		private void ReadConfiguration(string fileName) {
			var configXml = XDocument.Load(fileName);
			var root = configXml.Root;
			Require.NotNull(root);
			foreach (var property in root.Elements(CONFIG_PROPERTY_ELEMENT)) {
				var key = property.Attribute(CONFIG_PROPERTY_NAME_ATTRIBUTE);
				var value = property.Attribute(CONFIG_PROPERTY_VALUE_ATTRIBUTE);
				Require.NotNull(key);
				Require.NotNull(value);
				_properties[key.Value] = value.Value;
			}
		}
		public string GetString(string key) {
			return (string) _properties[key];
		}
		public bool GetBool(string key) {
			return bool.Parse((string) _properties[key]);
		}
	}
}
